/*************************************************
 * HISTORY:                                      *
 *	06/22/2020 pyx : Created.                    *
 *	06/01/2022 pyx : Edited.                     *
=================================================*/

#ifndef DATRANSFORMER_SYMBOLTABLE_H
#define DATRANSFORMER_SYMBOLTABLE_H

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <vector>
#include <string>
#include <iostream>
#include <fstream>

#include "DATransformerFileManager.h"
#include "DAType.h"
#include "DATransformerConnector.h"

class SymbolTable
{
public:
	struct Symbol
	{
		//unsigned sid;
		std::string signature;
		SymbolType st;
		std::string name;
	};

	struct Ref
	{
		unsigned refid;
		unsigned sid;
		unsigned fid;
		RefType rt;
		std::string loc;
	};

	struct SDep
	{
		unsigned ssid;//local, global after mapping
		unsigned sfid;
		unsigned esid;//local, global after mapping
		std::string efilepath;
		SDependencyType sdt;

	};

	SymbolTable(FileManager* fm);
	~SymbolTable();

	void insertDef(unsigned sid, unsigned fid, RefType rt, std::string location);
	void insertDec(unsigned sid, unsigned fid, RefType rt, std::string location);
	void insertRef(unsigned sid, unsigned fid, RefType rt, std::string location);
	void insertSymbolDep(unsigned ssid, unsigned sfid, unsigned esid, std::string efilepath, SDependencyType sdt);


	void mappingSymbolDep(std::map<std::pair<unsigned,unsigned>,unsigned>& sidMap);

	unsigned getsid(std::string signature, SymbolType st, std::string name);
	Symbol *getSymbol(unsigned sid);

	void finilize();

private:

	unsigned insertSymbol(std::string signature, SymbolType st, std::string name);//private

	FileManager* m_fm = nullptr;

	std::string mainfilepath; //used in finilize()
	std::string logpath;

	std::vector<Symbol *> m_st;								 //sid from 1,equals index+1
	std::unordered_map<std::string, unsigned> symbolIDTable; //sid from 1,indexed by symbol sig

	//std::unordered_map <unsigned,Ref*> refTable;//refid from 1,refid->ref

	unsigned currRefid = 1; //assume ref never repaet!!!!is it correct?
	unsigned currSymDepid = 1;
	std::vector<Ref *> globalDefTable;
	std::vector<Ref *> globalDecTable;
	std::vector<Ref *> refTable;

	std::vector<SDep *>symbolDepTable;//symdep might duplicated, ignore, handle it when inserting in mysql(& alloc symdepid)
	int sdepsidx = 0;
};

#endif